package cn.hpclub.server.controller.admin;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;

import cn.hpclub.server.model.SalesPromotion;
import cn.hpclub.server.service.ActivityBusinessReportService;

public class ActivityBusinessReportController extends BaseAdminController<SalesPromotion>{
    private static final String DAY_LIVENESS           = "dayLiveness";
    private static final String MONTH_LIVENESS         = "monthLiveness";
    private static final String SALES_4G               = "sales4g";
    private static final String MONTH_SALES_4G         = "monthSales4g";
    private static final String RETURNED_FARE_20       = "returnedFare20";
    private static final String MONTH_RETURNED_FARE_20 = "monthReturnedFare20";
    private static final String RETURNED_FARE_30       = "returnedFare30";
    private static final String MONTH_RETURNED_FARE_30 = "monthReturnedFare30";

    private static Logger       logger                 = LoggerFactory
            .getLogger(ActivityBusinessReportController.class);
    private static final String ORG_ID                 = "org_id";

    public void list(){
        int defaultOrgId = initOrgTree();
        initMonthList();
        // 搜索字段
        int orgId = defaultOrgId;
        ConcurrentHashMap<String, String> searchInfo = getSearchInfo();
        if(searchInfo.get(ORG_ID) == null){
            searchInfo.put(ORG_ID, String.valueOf(defaultOrgId));
        } else{
            orgId = Integer.parseInt(searchInfo.get(ORG_ID));
        }
        // 统计制定日期的活跃度，默认今天
        String selectDate = searchInfo.get("select_date");
        if(selectDate == null){
            selectDate = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
            searchInfo.put("select_date", DateFormatUtils.format(new Date(), selectDate));
        }
        String selectMonth = searchInfo.get("select_month");
        if(selectMonth == null){
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
            selectMonth = format.format(new Date());
            searchInfo.put("select_month", selectMonth);
        }

        Record channelVillage = new Record();
        Record channelOpen = new Record();
        Record channelOpenFirm = new Record();
        Record channelOthers = new Record();
        Record channelAll = new Record();

        ActivityBusinessReportService service = ActivityBusinessReportService.service;
        getDayData(orgId, selectDate, channelVillage, channelOpen, channelOpenFirm, channelOthers, channelAll, service);
        String monthTitle = selectMonth;
        String firstDayOfMonth = selectMonth + "-01";

        if(getThisMonth().equals(selectMonth)){
            if(getToday().equals(firstDayOfMonth)){
                // 本月第一天不统计本月数据
                monthTitle = selectMonth + "(暂无本月数据)";
            } else{
                monthTitle = selectMonth + "-01" + "至" + getYesterday();
                getMonthData(orgId, selectMonth, channelVillage, channelOpen, channelOpenFirm, channelOthers,
                             channelAll, service);
            }
        } else{
            monthTitle = selectMonth;
            getMonthData(orgId, selectMonth, channelVillage, channelOpen, channelOpenFirm, channelOthers, channelAll,
                         service);
        }
        setAttr("villageChannel", channelVillage);
        setAttr("openChannel", channelOpen);
        setAttr("openChannelFirm", channelOpenFirm);
        setAttr("restChannel", channelOthers);
        setAttr("allChannel", channelAll);
        setAttr("monthTitle", monthTitle);
        setAttrs(searchInfo);
        render("/admin/activity_business_report.tpl");
    }

    /**
     * @Title: getDayData
     * @Description:TODO
     * @param orgId
     * @param selectDate
     * @param channelVillage
     * @param channelOpen
     * @param channelOpenFirm
     * @param channelOthers
     * @param channelAll
     * @param service
     *            void
     */

    private void getDayData(int orgId, String selectDate, Record channelVillage, Record channelOpen,
            Record channelOpenFirm, Record channelOthers, Record channelAll, ActivityBusinessReportService service){
        // 日活跃度统计
        getDayLiveness(orgId, selectDate, channelVillage, channelOpen, channelOpenFirm, channelOthers, channelAll,
                       service);
        // 4G终端销售日统计
        get4gSales(orgId, selectDate, channelVillage, channelOpen, channelOpenFirm, channelOthers, channelAll, service);
        // 送费20元日统计
        getReturnedFare(orgId, selectDate, channelVillage, channelOpen, channelOpenFirm, channelOthers, channelAll,
                        service, RETURNED_FARE_20, 20);
        // 送费30元日统计
        getReturnedFare(orgId, selectDate, channelVillage, channelOpen, channelOpenFirm, channelOthers, channelAll,
                        service, RETURNED_FARE_30, 30);
    }

    /**
     * @Title: getMonthData
     * @Description:TODO
     * @param orgId
     * @param selectMonth
     * @param channelVillage
     * @param channelOpen
     * @param channelOpenFirm
     * @param channelOthers
     * @param channelAll
     * @param service
     *            void
     */

    private void getMonthData(int orgId, String selectMonth, Record channelVillage, Record channelOpen,
            Record channelOpenFirm, Record channelOthers, Record channelAll, ActivityBusinessReportService service){
        // 月活跃度统计
        getMonthLiveness(orgId, channelVillage, channelOpen, channelOpenFirm, channelOthers, channelAll, service,
                         selectMonth);
        // 送费20元月统计
        getMonthReturnedFare(orgId, channelVillage, channelOpen, channelOpenFirm, channelOthers, channelAll, service,
                             selectMonth, ActivityBusinessReportService.COUNT_TYPE_DAILY_20_YUAN,
                             MONTH_RETURNED_FARE_20);
        // 4G终端销售月统计
        getMonth4gSales(orgId, channelVillage, channelOpen, channelOpenFirm, channelOthers, channelAll, service,
                        selectMonth);
        // 退费30元月统计
        getMonthReturnedFare(orgId, channelVillage, channelOpen, channelOpenFirm, channelOthers, channelAll, service,
                             selectMonth, ActivityBusinessReportService.COUNT_TYPE_DAILY_PRODUCT_30YUAN,
                             MONTH_RETURNED_FARE_30);
    }

    private String getThisMonth(){
        DateFormat f = new SimpleDateFormat("yyyy-MM");
        return f.format(new Date());
    }

    private String getToday(){
        DateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        return f.format(new Date());
    }

    private String getYesterday(){
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, -1);
        return f.format(calendar.getTime());
    }

    private void initMonthList(){
        List<String> list = new ArrayList<String>();
        DateFormat f = new SimpleDateFormat("yyyy-MM");
        Date startDate = null;
        final String configMonth = getConfigValue("ACT_SALES_DAILY_COUNT_START_DATE");
        try{
            startDate = f.parse(configMonth + "-01");
        }
        catch(ParseException e){
            e.printStackTrace();
        }

        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        String month = f.format(c.getTime());
        String currentMonth = f.format(new Date());
        System.out.println("currentMonth:" + currentMonth);
        System.out.println("month:" + month);
        while(month.compareTo(currentMonth) <= 0){
            list.add(f.format(c.getTime()));
            c.add(Calendar.MONTH, 1);
            month = f.format(c.getTime());
        }
        setAttr("monthList", list);
    }

    private String getConfigValue(String key){
        String sql = "SELECT * FROM sys_code_value WHERE code=? AND is_deleted=0";
        Record record = Db.findFirst(sql, key);
        if(record == null){
            return "";
        }
        return record.getStr("value");
    }

    private void getDayLiveness(int orgId, String date, Record channelVillage, Record channelOpen,
            Record channelOpenFirm, Record restChannel, Record allChannel, ActivityBusinessReportService service){
        // 计算村渠日活跃度
        long village = service.getLiveness4ChannelVillage(date, date, orgId);
        channelVillage.set(DAY_LIVENESS, village);
        // 计算开渠日活跃度
        long open = service.getLiveness4ChannelOpen(date, date, orgId);
        channelOpen.set(DAY_LIVENESS, open);
        // 计算开渠厂促日活跃度
        long openFirm = service.getLiveness4ChannelOpenFirm(date, date, orgId);
        channelOpenFirm.set(DAY_LIVENESS, openFirm);
        // 统计大掌柜整体日活跃度
        long all = service.getLivenessChannelAll(date, date, orgId);
        allChannel.set(DAY_LIVENESS, all);
        // 计算其他渠道日活跃度
        long others = all - village - open - openFirm;
        restChannel.set(DAY_LIVENESS, others);
    }

    private void getMonthLiveness(int orgId, Record channelVillage, Record channelOpen, Record channelOpenFirm,
            Record channelRest, Record channelAll, ActivityBusinessReportService service, String selectMonth){
        // 计算村渠月活跃度
        long village = service.getCountFromDailyCount(ActivityBusinessReportService.COUNT_TYPE_DAILY_LIVENESS,
                                                      ActivityBusinessReportService.CHANNEL_TYPE_VILLAGE, selectMonth,
                                                      orgId);
        channelVillage.set(MONTH_LIVENESS, village);
        // 计算开渠月活跃度
        long open = service.getCountFromDailyCount(ActivityBusinessReportService.COUNT_TYPE_DAILY_LIVENESS,
                                                   ActivityBusinessReportService.CHANNEL_TYPE_OPEN, selectMonth, orgId);
        channelOpen.set(MONTH_LIVENESS, open);
        // 计算开渠厂促月活跃度
        long openFirm = service.getCountFromDailyCount(ActivityBusinessReportService.COUNT_TYPE_DAILY_LIVENESS,
                                                       ActivityBusinessReportService.CHANNEL_TYPE_OPEN_FIRM,
                                                       selectMonth, orgId);
        channelOpenFirm.set(MONTH_LIVENESS, openFirm);
        // 统计大掌柜整体月活跃度
        long all = service.getCountFromDailyCount(ActivityBusinessReportService.COUNT_TYPE_DAILY_LIVENESS,
                                                  ActivityBusinessReportService.CHANNEL_TYPE_ALL, selectMonth, orgId);
        channelAll.set(MONTH_LIVENESS, all);
        // 计算其他渠道月活跃度
        long monthLivenessOthersChannel = all - village - open - openFirm;
        channelRest.set(MONTH_LIVENESS, monthLivenessOthersChannel);
    }

    private void get4gSales(int orgId, String date, Record channelVillage, Record channelOpen, Record channelOpenFirm,
            Record channelOthers, Record channelAll, ActivityBusinessReportService service){
        // 计算村渠日活跃度
        long village = service.get4gSales4ChannelVillage(date, date, orgId);
        channelVillage.set(SALES_4G, village);
        // 计算开渠日活跃度
        long open = service.get4gSales4ChannelOpen(date, date, orgId);
        channelOpen.set(SALES_4G, open);
        // 计算开渠厂促日活跃度
        long openFirm = service.get4gSales4ChannelOpenFirm(date, date, orgId);
        channelOpenFirm.set(SALES_4G, openFirm);
        // 统计大掌柜整体日活跃度
        long all = service.get4gSalesLivenessChannelAll(date, date, orgId);
        channelAll.set(SALES_4G, all);
        // 计算其他渠道日活跃度
        long others = all - village - open - openFirm;
        channelOthers.set(SALES_4G, others);
    }

    private void getMonth4gSales(int orgId, Record channelVillage, Record channelOpen, Record channelOpenFirm,
            Record channelOthers, Record channelAll, ActivityBusinessReportService service, String selectMonth){
        // 计算村渠月活跃度
        long village = service.getCountFromDailyCount(ActivityBusinessReportService.COUNT_TYPE_DAILY_PRODUCT,
                                                      ActivityBusinessReportService.CHANNEL_TYPE_VILLAGE, selectMonth,
                                                      orgId);
        channelVillage.set(MONTH_SALES_4G, village);
        // 计算开渠月活跃度
        long open = service.getCountFromDailyCount(ActivityBusinessReportService.COUNT_TYPE_DAILY_PRODUCT,
                                                   ActivityBusinessReportService.CHANNEL_TYPE_OPEN, selectMonth, orgId);
        channelOpen.set(MONTH_SALES_4G, open);
        // 计算开渠厂促月活跃度
        long openFirm = service.getCountFromDailyCount(ActivityBusinessReportService.COUNT_TYPE_DAILY_PRODUCT,
                                                       ActivityBusinessReportService.CHANNEL_TYPE_OPEN_FIRM,
                                                       selectMonth, orgId);
        channelOpenFirm.set(MONTH_SALES_4G, openFirm);
        // 统计大掌柜整体月活跃度
        long all = service.getCountFromDailyCount(ActivityBusinessReportService.COUNT_TYPE_DAILY_PRODUCT,
                                                  ActivityBusinessReportService.CHANNEL_TYPE_ALL, selectMonth, orgId);
        channelAll.set(MONTH_SALES_4G, all);
        // 计算其他渠道月活跃度
        long others = all - village - open - openFirm;
        channelOthers.set(MONTH_SALES_4G, others);
    }

    private void getReturnedFare(int orgId, String date, Record channelVillage, Record channelOpen,
            Record channelOpenFirm, Record channelOthers, Record channelAll, ActivityBusinessReportService service,
            String key, int amount){
        // 计算村渠日活跃度
        long village = service.getReturnedFare4ChannelVillage(date, date, orgId, amount);
        channelVillage.set(key, village);
        // 计算开渠日活跃度
        long open = service.getReturnedFare4ChannelOpen(date, date, orgId, amount);
        channelOpen.set(key, open);
        // 计算开渠厂促日活跃度
        long openFirm = service.getReturnedFare4ChannelOpenFirm(date, date, orgId, amount);
        channelOpenFirm.set(key, openFirm);
        // 统计大掌柜整体日活跃度
        long all = service.getReturnedFare4ChannelAll(date, date, orgId, amount);
        channelAll.set(key, all);
        // 计算其他渠道日活跃度
        long others = all - village - open - openFirm;
        channelOthers.set(key, others);
    }

    private void getMonthReturnedFare(int orgId, Record channelVillage, Record channelOpen, Record channelOpenFirm,
            Record channelOthers, Record channelAll, ActivityBusinessReportService service, String selectMonth,
            int countType, String feiledName){
        // 计算村渠月活跃度
        long village = service.getCountFromDailyCount(countType, ActivityBusinessReportService.CHANNEL_TYPE_VILLAGE,
                                                      selectMonth, orgId);
        channelVillage.set(feiledName, village);
        // 计算开渠月活跃度
        long open = service.getCountFromDailyCount(countType, ActivityBusinessReportService.CHANNEL_TYPE_OPEN,
                                                   selectMonth, orgId);
        channelOpen.set(feiledName, open);
        // 计算开渠厂促月活跃度
        long openFirm = service.getCountFromDailyCount(countType, ActivityBusinessReportService.CHANNEL_TYPE_OPEN_FIRM,
                                                       selectMonth, orgId);
        channelOpenFirm.set(feiledName, openFirm);
        // 统计大掌柜整体月活跃度
        long all = service.getCountFromDailyCount(countType, ActivityBusinessReportService.CHANNEL_TYPE_ALL,
                                                  selectMonth, orgId);
        channelAll.set(feiledName, all);
        // 计算其他渠道月活跃度
        long others = all - village - open - openFirm;
        channelOthers.set(feiledName, others);
    }

}
